#!/bin/bash

#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2020-2021 Xilinx, Inc.
#
# xbmgmt loader which automatically switches between classic and next
# generation xbmgmt utility. The current default is classic xbmgmt tool.
#

# -- Detect a Windows environment and automatically switch to the .bat file
if [[ "`uname`" == windows32* ]] || [[ "`uname`" == CYGWIN* ]] ; then
  trap "" INT
  "$0.bat" "$@"
  exit $?
fi

DEFAULT=xbmgmt
XBMGMT=xbmgmt
XBMGMT2=xbmgmt2

# Table to resolve reset sub-command based on switch passed to reset
declare -A RSTOPT=( \
        ["--hot"]="XBMGMT" \
        ["--kernel"]="XBMGMT" \
        ["--ecc"]="XBMGMT" \
        ["--softkernel"]="XBMGMT" \
        ["--ert"]="XBMGMT" \
        ["--card"]="XBMGMT" \
        ["--force"]="XBMGMT" \
        ["--device"]="XBMGMT2" \
        ["--type"]="XBMGMT2" \
        ["--help"]="XBMGMT2" \
        ["-d"]="XBMGMT2" \
        ["-r"]="XBMGMT2" \
        ["-h"]="XBMGMT2" \
    )

# In the following table "reset" points to a second table by name
# Note that reset is valid both for classic and next generation tool
# and hence requires a second lookup to resolve between xbmgmt and xbmgmt2
declare -A COMMANDS=( \
        ["help"]="XBMGMT" \
        ["version"]="XBMGMT" \
        ["--version"]="XBMGMT" \
        ["scan"]="XBMGMT" \
        ["flash"]="XBMGMT" \
        ["-lash"]="XBMGMT" \
        ["reset"]="RSTOPT" \
        ["clock"]="XBMGMT" \
        ["partition"]="XBMGMT" \
        ["config"]="XBMGMT" \
        ["nifd"]="XBMGMT" \
        ["hotplug"]="XBMGMT" \
        ["examine"]="XBMGMT2" \
        ["program"]="XBMGMT2" \
        ["dump"]="XBMGMT2" \
        ["advanced"]="XBMGMT2" \
        ["--help"]="XBMGMT2" \
        ["--verbose"]="XBMGMT2" \
        ["--batch"]="XBMGMT2" \
        ["-h"]="XBMGMT2" \
        ["-v"]="XBMGMT2" \
        ["-b"]="XBMGMT2" \
    )


# Working variables
XRT_PROG=${DEFAULT}

# Determine which version of xbmgmt should be used
# Check to see environment variable is NOT set
if [ -z ${XRT_TOOLS_NEXTGEN+x} ]; then
  XRT_PROG=xbmgmt
elif [ "${XRT_TOOLS_NEXTGEN,,}" = "true" ]; then
     XRT_PROG=xbmgmt2
fi

# Examine the options and look for -new/--new
XRTWARP_PROG_ARGS_size=0
XRTWRAP_PROG_ARGS=()
while [ $# -gt 0 ]; do
  case "$1" in
    # Indicates that the new version of xbmgmt (e.g., xbmgmt2) should be used
    -new|--new)
      XRT_PROG=xbmgmt2
      shift
      ;;
    # Copy the options the remaining options
    *)
      XRTWRAP_PROG_ARGS[$XRTWARP_PROG_ARGS_size]="$1"
      XRTWARP_PROG_ARGS_size=$(($XRTWARP_PROG_ARGS_size + 1))
      shift
      ;;
  esac
done

# If user did not specify -new/--new then attempt to determine if user
# wants to use classic or new by peeking inside the command line
# Ideally with bash 'nameref' the case/esac would not be necessary and
# we should be able to deref in one step using helper declaration like
# declare -n PROG=${COMMANDS[${XRTWRAP_PROG_ARGS[0]}]}
# However RHEL 7.X still uses bash 4.2 which does not support nameref :-(

if [ ${XRT_PROG} == "xbmgmt" ]; then
  PROG=${COMMANDS[${XRTWRAP_PROG_ARGS[0]}]}
  case ${PROG} in
    XBMGMT | XBMGMT2)
      # Get named reference to the value pointed by the string returned
      XRT_PROG=${!PROG}
      ;;
    RSTOPT)
      # We have an ambiguous sub-command, use the next token/switch to
      # disambiguate by a second look up
      if [ ${#XRTWRAP_PROG_ARGS[@]} -gt 1 ]; then
        PROG=${RSTOPT[${XRTWRAP_PROG_ARGS[1]}]:-${DEFAULT}}
        XRT_PROG=${!PROG}
      else
        # User did not provide switch to the sub-command so we cannot
        # disabmiguate, default to DEFAULT
        XRT_PROG=${DEFAULT}
      fi
      ;;
    *)
      # Bogus sub-command which failed lookup
      XRT_PROG=${DEFAULT}
      ;;
  esac
fi

# Friendly message
if [ ${XRT_PROG} == "xbmgmt2" ]; then
  echo "-----------------------------------------------------"
  echo " Invoking next generation of the xbmgmt application "
  echo "-----------------------------------------------------"
fi

# -- Find and call the loader
XRT_LOADER="`dirname \"$0\"`/unwrapped/loader"

if [ ! -f "$XRT_LOADER" ]; then
  echo "ERROR: Could not find 64-bit loader executable."
  echo "ERROR: ${XRT_LOADER} does not exist."
  exit 1
fi

"${XRT_LOADER}" -exec $XRT_PROG "${XRTWRAP_PROG_ARGS[@]}"
